package com.atguigu.zk.distributedlock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * 第三方 Curator 框架实现分布式锁案例
 * 测试同线程是否能重复获取锁：可以
 * 测试不同线程是否可以同步，正常运行不冲突：是
 */
public class CuratorLockTest {
    public static void main(String[] args) {


        // 创建分布式锁1
        // public InterProcessMutex(CuratorFramework client, String path) {
        // CuratorFramework client 连接服务器的客户端
        // String path 针对哪一个路径进行监控
        InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework(), "/locks");


        // 创建分布式锁2
        InterProcessMutex lock2 = new InterProcessMutex(getCuratorFramework(), "/locks");



        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock1.acquire();
                    System.out.println("---线程1 启动，获取到锁");
                    // 测试锁重复获取
                    lock1.acquire();
                    System.out.println("---线程1 再次启动，获取到锁");

                    Thread.sleep(5*1000);
                    lock1.release();
                    System.out.println("---线程1 释放锁");
                    lock1.release();
                    System.out.println("---线程1 再次释放锁");

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock2.acquire();
                    System.out.println("---线程2 启动，获取到锁");
                    // 测试锁重复获取
                    lock2.acquire();
                    System.out.println("---线程2 再次启动，获取到锁");

                    Thread.sleep(5*1000);
                    lock2.release();
                    System.out.println("---线程2 释放锁");
                    lock2.release();
                    System.out.println("---线程2 再次释放锁");

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();



    }

    // 分布式锁初始化
    private static CuratorFramework getCuratorFramework() {

        // 重试策略，初试时间 3 秒，重试 3 次
        //  public ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries) {
        // int baseSleepTimeMs 多少秒之后开始重试
        // int maxRetries 要重试多少次
        ExponentialBackoffRetry exponentialBackoffRetry = new ExponentialBackoffRetry(3000, 3);

        // 通过工厂类创建一个CuratorFramework
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("lc01:2181,lc02:2181,lc03:2181") // server列表
                .connectionTimeoutMs(2000) // 连接超时时间
                .sessionTimeoutMs(2000) // 会话超时时间
                .retryPolicy(exponentialBackoffRetry) //连接失败后，间隔多少秒后开始下一次尝试
                .build();
        // 启动客户端
        client.start();
        System.out.println("zk客户端 启动并获取连接成功");

        return client;
    }

}
